package com.assignment.health.ui.qrcode

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.text.format.DateFormat
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.fragment.app.Fragment
import com.assignment.health.LoginActivity
import com.assignment.health.R
import com.google.zxing.BarcodeFormat
import com.user.UserInformation
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Url

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

data class NucleicAcid(val status: String, val message: String, val length: Int, val data: List<AcidRecord>) {
    data class AcidRecord(
        val place: String,
        val status: Int,
        val time: String
    )
}

data class TestColor(val status: String, val message: String, val color: Int)

interface TestColorRequest{
    @GET
    fun getRecord(@Url url: String): Call<TestColor>
}

interface NucleicAcidRequest{
//    UserInformation must be available
//    @Url
//    fun getRecord(): Call<NucleicAcid>
    @GET
    fun getRecord(@Url url: String): Call<NucleicAcid>
}

/**
 * A simple [Fragment] subclass.
 * Use the [HealthQRCode.newInstance] factory method to
 * create an instance of this fragment.
 */
class HealthQRCode : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    private var loading_image = R.drawable.ic_launcher_foreground
    private var temp_qr_info: Int = 0

    var arrayAdapter: ArrayAdapter<String>? = null

    fun kickOut() {
        val intent = Intent(activity, LoginActivity::class.java)
        startActivity(intent)
    }

    fun launchRequest() {
        if (UserInformation.available == 0) {
            kickOut()
            return
        }

        val url = "https://health.icys.top/"

        val rt = Retrofit.Builder().baseUrl(url).addConverterFactory(GsonConverterFactory.create()).build()
        val service = rt.create(NucleicAcidRequest::class.java)
        val bk = service.getRecord(("record/get-acid?limit=1&token=".plus(UserInformation.token)))

        bk.enqueue(object : Callback<NucleicAcid>{
            override fun onResponse(call: Call<NucleicAcid>, response: Response<NucleicAcid>) {
                val value = response.body()
                if (value != null && value.status == "OK") {
                    displayNewRecord(value)
                } else {
                    kickOut()
                }
            }

            override fun onFailure(call: Call<NucleicAcid>, t: Throwable) {
                print(t.stackTrace)
            }
        })
    }

    fun launchRequestColor() {
        if (UserInformation.available == 0) {
            kickOut()
            return
        }

        val url = "https://health.icys.top/"

        val rt = Retrofit.Builder().baseUrl(url).addConverterFactory(GsonConverterFactory.create()).build()
        val service = rt.create(TestColorRequest::class.java)
        val bk = service.getRecord(("user/get-color?token=".plus(UserInformation.token)))

        bk.enqueue(object : Callback<TestColor>{
            override fun onResponse(call: Call<TestColor>, response: Response<TestColor>) {
                val value = response.body()
                if (value != null && value.status == "OK") {

                    val encoder = QRCodeEncoder()

                    val good = value.color
                    val time=System.currentTimeMillis()
                    val format:CharSequence= DateFormat.format("yyyy"+"."+"MM"+"."+"dd"+"."+"hh:mm:ss"+"  "+"E", time)
                    val value = "{token: ${UserInformation.token}, record: ${value}, current_time: $format}"
                    if (good == 1) {
                        encoder.setForegroundColor(Color.GREEN)
                    } else if (good == 2) {
                        encoder.setForegroundColor(Color.rgb(174, 130, 15))
                    } else if (good == 3) {
                        encoder.setForegroundColor(Color.RED)
                    } else {
//                        Toast.makeText(activity, "Unknown Test Status: $good", Toast.LENGTH_LONG).show()
                        view?.findViewById<TextView>(R.id.text_acid_main_info)?.text = "No Record"
                        view?.findViewById<TextView>(R.id.text_acid_main_side_info)?.text = "No Record"

                        arrayAdapter?.notifyDataSetChanged()
                        return
                    }

                    System.out.println(good)

                    val bitmap = encoder.encodeBitmap(value, BarcodeFormat.QR_CODE, 800, 800)
                    view?.findViewById<ImageView>(R.id.image_QR_code)?.setImageBitmap(bitmap)
                } else {
                    kickOut()
                }
            }

            override fun onFailure(call: Call<TestColor>, t: Throwable) {
                print(t.stackTrace)
            }
        })
    }

    @SuppressLint("SetTextI18n")
    fun displayNewRecord(record: NucleicAcid) {
        if (record.length == 0) {
            view?.findViewById<TextView>(R.id.text_acid_main_info)?.text = "No Record"
            view?.findViewById<TextView>(R.id.text_acid_main_side_info)?.text = "No Record"
            arrayAdapter?.notifyDataSetChanged()
        } else {
            view?.findViewById<TextView>(R.id.text_acid_main_info)?.text = "Recorded at ".plus(record.data[0].time)
            view?.findViewById<TextView>(R.id.text_acid_main_side_info)?.text = "tested at ".plus(record.data[0].place)


            arrayAdapter?.notifyDataSetChanged()
        }
    }

    fun updateRecord(){
        val my_image_view = view?.findViewById<ImageView>(R.id.image_QR_code)
        view?.findViewById<TextView>(R.id.text_acid_main_info)?.setText(R.string.wu_acid_test)
        my_image_view?.setImageResource(loading_image)
        arrayAdapter?.notifyDataSetChanged()

        launchRequest()

        launchRequestColor()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_health_qr_code, container, false)
        arrayAdapter = activity?.let { ArrayAdapter<String>(it, R.layout.fragment_health_qr_code) }

        temp_qr_info = 0

        val my_image_view = view?.findViewById<ImageView>(R.id.image_QR_code)
        my_image_view?.setImageResource(loading_image)
        arrayAdapter?.notifyDataSetChanged()

        updateRecord()

        view.setOnClickListener { updateRecord() }

        val handler: Handler = @SuppressLint("HandlerLeak")
        object :Handler() {
            @SuppressLint("SetTextI18n")
            override fun handleMessage(msg: Message) {
                super.handleMessage(msg)
                when (msg.what) {
                    1 -> {
                        val time=System.currentTimeMillis()
                        val format:CharSequence= DateFormat.format("yyyy"+"."+"MM"+"."+"dd"+"."+"hh:mm:ss"+"  "+"E", time)
                        view.findViewById<TextView>(R.id.text_current_time).text = "current time: ".plus(format)
                    }
                    else -> {
                    }
                }
            }
        }

        object : Thread() {
            override fun run() {
                do {
                    sleep(1000)
                    val message= Message()
                    message.what=1
                    handler.sendMessage(message)
                }while (true)
            }
        }.start()

        return view
    }

    companion object {
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment HealthQRCode.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            HealthQRCode().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}